import React from 'react';
import { SoundOutlined } from '@ant-design/icons';
import { notification, message } from 'antd';

import { getSocketToken } from '@/services/api';
import Notice from '@/pages/Notice';
import * as socketService from '@/services/socket';

export const SocketActions = {
  delayUpdate: 'delayUpdate',
  subSocketChannel: 'subSocketChannel',
  handleReconnect: 'handleReconnect',
  handleUpdateBatchTask: 'handleUpdateBatchTask',
  addToBatchTaskList: 'addToBatchTaskList',
  removeFromBatchTaskList: 'removeFromBatchTaskList',
  findBatchTask: 'findBatchTask',
};
const namespace = 'socket';
const Model = {
  namespace,
  state: {
    batchTaskList: [],
  },
  effects: {
    *findBatchTask(
      {
        payload: { namespace: fNamespace, batchId: fBatchId },
      },
      { select }
    ) {
      const batchTaskList = yield select(state => state.socket.batchTaskList);

      const index = batchTaskList.findIndex(
        item => item.modelNamespace === fNamespace && item.batchId === fBatchId
      );
      return index >= 0;
    },
    *subSocketChannel(
      {
        payload: { batchTask },
      },
      { call, put }
    ) {
      yield call(socketService.socketChannel, {
        type: 'sub',
        data: {
          to: batchTask.batchId,
          type: 'task',
        },
      });
      yield put({
        type: SocketActions.addToBatchTaskList,
        payload: { batchTask },
      });
      console.log('订阅成功');
    },
    *handleReconnect(_, { select, put }) {
      const batchTaskList = yield select(state => state.socket.batchTaskList);
      console.log('batchTaskList: ', batchTaskList);
      if (batchTaskList && batchTaskList.length > 0) {
        console.info('开始重新订阅批量');
        try {
          yield batchTaskList.map(batchTask => {
            console.log(batchTask);
            return put({
              type: 'subSocketChannel',
              payload: { batchTask },
            });
          });
        } catch (e) {
          console.error('批量再次订阅出现异常');
        }
      } else {
        console.info('没有找到批量记录');
      }
    },
    *handleUpdateBatchTask(
      {
        payload: { successProp, batchId },
      },
      { put }
    ) {
      if (successProp >= 100) {
        yield put({
          type: 'removeFromBatchTaskList',
          payload: { batchId },
        });
      }
    },
    // socket连接成功
    *connectSuccess(_, { select, put }) {
      const {
        login: { systemList = [] },
        global: { socketToken = null },
      } = yield select(state => state);
      if (systemList.length) {
        if (socketToken) {
          yield put({
            type: 'checkSocketToken',
            payload: {
              token: socketToken,
            },
          });
        } else {
          console.log(socketToken,'socketToken');
          yield put({
            type: 'fetchSocketToken',
          });
        }
      }
    },
    // 获取socketToken
    *fetchSocketToken(_, { call, put }) {
      const responseSocketToken = yield call(getSocketToken);
      console.log(responseSocketToken,"responseSocketTokenresponseSocketToken");
      if (responseSocketToken.success && responseSocketToken.data) {
        yield put({
          type: 'checkSocketToken',
          payload: {
            token: responseSocketToken.data.token,
          },
        });
        yield put({
          type: 'global/updateModelData',
          payload: {
            socketToken: responseSocketToken.data.token,
          },
        });
      } else {
        message.warning(responseSocketToken.message || '服务端错误！');
      }
    },
    // 验证socketToken
    *checkSocketToken(
      {
        payload: { token },
      },
      { call, put }
    ) {
      // 通过websocket请求
      const socketResp = yield call(socketService.socketChannel, {
        type: 'socket/auth',
        data: { token },
      });

      if (!socketResp.success) {
        yield put({
          type: 'fetchSocketToken',
        });
      } else {
        console.log('验证通过重新订阅');
        // 验证通过重新订阅
        yield put({
          type: 'handleReconnect',
        });
      }
    },

    // 消息提示
    *socketNotice(
      {
        payload: { data, dispatch },
      },
      { put }
    ) {
      yield put.resolve({
        type: 'global/fetchNoticeNum',
        payload: {},
      });
      let noticeContent = {};
      noticeContent = {
        message: data.title,
        top: 65,
        icon: <SoundOutlined style={{ color: '#fe5d58' }} />,
        description: data.content,
        onClick: () => {
          if (data.sendType === 1) {
            return;
          }
          put({
            type: 'global/changeNoticeReadState',
            payload: { sysMsgId: data.id, vno: data.vno },
          });
        },
      };
      if (data.sendType === 1) {
        noticeContent = {
          ...noticeContent,
          btn: <Notice dispatch={dispatch} data={data} location={window.location} />,
        };
      }
      yield notification.info(noticeContent);
    },
  },
  reducers: {
    *delayUpdate(_, { delay }) {
      yield delay(1000);
    },
    addToBatchTaskList(
      state,
      {
        payload: { batchTask },
      }
    ) {
      return {
        ...state,
        batchTaskList: [...state.batchTaskList, batchTask],
      };
    },
    removeFromBatchTaskList(
      state,
      {
        payload: { batchId },
      }
    ) {
      const index = state.batchTaskList.findIndex(task => task.batchId === batchId);
      const list = [...state.batchTaskList];
      list.splice(index, 1);
      return {
        ...state,
        batchTaskList: [...list],
      };
    },
  },
  subscriptions: {
    socket({ dispatch }) {
      socketService.listen(action => {
        switch (action.type) {
          case 'connect':
            if (action.success) {
              dispatch({
                type: 'connectSuccess',
              });
            } else {
              dispatch({
                type: 'connectFail',
              });
            }
            break;
          // case 'reconnect':
          //   if (action.success) {
          //     dispatch({
          //       type: 'connectSuccess',
          //     });
          //   } else {
          //     dispatch({
          //       type: 'connectFail',
          //     });
          //   }
          //   break;
          case 'notice':
            dispatch({
              type: 'socketNotice',
              payload: { data: action.data, dispatch },
            });
            break;
          default:
        }
      });
    },
  },
};

/**
 * 批量任务对象工厂
 * @param {string} batchId
 * @param {string} modelNamespace
 * @param {string} modelType
 */
export function batchTaskFactory(batchId, modelNamespace, modelType) {
  if (!namespace || !modelType || !batchId) {
    throw new Error('缺少必要参数');
  }
  return {
    batchId,
    modelNamespace,
    modelType,
  };
}

export default Model;
